﻿using DevExpress.Mvvm.Gantt;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

namespace DevWpfApp
{
    public class ProjectTaskViewModel
    {
        public ObservableCollection<GanttTask> Tasks { get; set; }

        public ObservableCollection<GanttResource> Resources { get; set; }

        private void UpdateTaskId()
        {
            foreach (var task in Tasks)
            {
                if (task.Id == task) // 这是什么幺儿子
                {
                    task.Id = IntIdGenerator.NewId();
                }
            }
        }

        private void UpdateTaskParentId()
        {
            foreach (var task in Tasks)
            {
                if (task.ParentId is GanttTask)// 新的幺儿子
                {
                    task.ParentId = ((GanttTask)task.ParentId).Id;
                }
            }
        }

        internal void UpdateId()
        {
            UpdateTaskParentId();
            UpdateTaskId();
            UpdateTaskPreId();
        }

        public int CountTask()
        {
            Dictionary<int, bool> ishaschildrens = new Dictionary<int, bool>();
            foreach(var task in Tasks)
            {
                int id = (int)task.Id;
                if (ishaschildrens.ContainsKey(id)==false)
                    ishaschildrens.Add(id, false);
                if(task.ParentId!=null)
                {
                    int pid = (int)task.ParentId;
                    if (ishaschildrens.ContainsKey(pid))
                        ishaschildrens[pid] = true;
                    else
                        ishaschildrens.Add(pid, true);
                }
            }
            return (from p in ishaschildrens
                    where p.Value == false
                    select p).Count();
        }
        
        private void UpdateTaskPreId()
        {
            foreach (var task in Tasks)
            {
                foreach (var pt in task.PredecessorLinks)
                {
                    if ((pt.PredecessorTaskId is GanttTask))// 又一个幺儿子
                    {
                        pt.PredecessorTaskId = ((GanttTask)pt.PredecessorTaskId).Id;
                    }
                }
            }
        }

        internal string _password = "";
        public void Save(string filename)
        {
            if (File.Exists(filename + ".bak"))
                File.Delete(filename + ".bak");
            if(File.Exists(filename))
                File.Copy(filename, filename + ".bak");
            try
            {
                UpdateTaskId();
                UpdateTaskParentId();
                UpdateTaskPreId();
                var obj = new GanttTaskCollectionProxy { Tasks = Tasks, Resources = Resources };
                CryptoHelper.Save<GanttTaskCollectionProxy>(filename, _password, obj);

            }
            catch (Exception ex)
            {
                try
                {
                    var obj2 = new GanttTaskCollectionProxy { Tasks = Tasks, Resources = Resources };
                    CryptoHelper.Save<GanttTaskCollectionProxy>(filename + ".txt", "", obj2);
                }
                catch (Exception ex2)
                {

                }
                MessageBox.Show(ex.Message);
                File.Delete(filename);
                File.Copy(filename + ".bak", filename);
                File.Delete(filename + ".bak");

            }
        }


        public void Load(string filename)
        {
            GanttTaskCollectionProxy cp = null;
            try
            {
                cp = CryptoHelper.Load<GanttTaskCollectionProxy>(filename, _password);
            }
            catch (Exception ex)
            {
                InputPasswordWindow win = new InputPasswordWindow();
                if (win.ShowDialog() == true)
                {
                    cp = CryptoHelper.Load<GanttTaskCollectionProxy>(filename, win.Password);
                    _password = win.Password;
                }
            }
            if (cp != null)
            {
                this.Tasks = cp.Tasks;
                this.Resources = cp.Resources;
            }
        }

        public ProjectTaskViewModel()
        {
            Resources = new ObservableCollection<GanttResource>{
                    new GanttResource() {Id=0,Name="陆松" },
                };

            Tasks = new ObservableCollection<GanttTask> {
                    new GanttTask() {
                        Id = 0,
                        Name = "Add a new feature",
                        StartDate = DateTime.Now.AddDays(-1),
                        FinishDate = DateTime.Now.AddDays(6)
                    },
                    new GanttTask() {
                        Id =1,
                        ParentId = 0,
                        Name = "Write the code",
                        StartDate = DateTime.Now.AddDays(-1),
                        FinishDate = DateTime.Now.AddDays(2),

                    },
                    new GanttTask() {
                        Id = 2,
                        ParentId = 0,
                        Name = "Write the docs",
                        StartDate = DateTime.Now.AddDays(2),
                        FinishDate = DateTime.Now.AddDays(5)
                    },
                    new GanttTask() {
                        Id = 3,
                        ParentId = 0,
                        Name = "Test the new feature",
                        StartDate = DateTime.Now.AddDays(2),
                        FinishDate = DateTime.Now.AddDays(5)
                    },
                    new GanttTask() {
                        Id = 4,
                        ParentId = 0,
                        Name = "Release the new feature",
                        StartDate = DateTime.Now.AddDays(5),
                        FinishDate = DateTime.Now.AddDays(6),
                    }
                };


            // the "Release the new feature" task can begin only when the "Write the docs" task is complete
            Tasks[4].PredecessorLinks.Add(new GanttPredecessorLink() { PredecessorTaskId = 2, LinkType = PredecessorLinkType.FinishToStart });
            // the "Release the new feature" task can begin only when the "Test the new feature" task is complete
            Tasks[4].PredecessorLinks.Add(new GanttPredecessorLink() { PredecessorTaskId = 3, LinkType = PredecessorLinkType.FinishToStart });
            // the "Write the docs" task can begin only when the "Write the code" task is complete
            Tasks[2].PredecessorLinks.Add(new GanttPredecessorLink() { PredecessorTaskId = 1, LinkType = PredecessorLinkType.FinishToStart });
            // the "Test the new feature" task can begin only when the "Write the code" task is complete
            Tasks[3].PredecessorLinks.Add(new GanttPredecessorLink() { PredecessorTaskId = 1, LinkType = PredecessorLinkType.FinishToStart });

        }

    }
}
